local json = require "json"
local stats = require "stats"
stats.on()
local shader = love.graphics.newShader([[
    varying float texIdx;
    #ifdef VERTEX
    attribute float tIdx;
    vec4 position( mat4 transform_projection, vec4 vertex_position )
    {
        texIdx = tIdx;
        vec4 position = transform_projection * vertex_position;
        return position;
    }
    #endif

    #ifdef PIXEL
    extern Image tex1;
    extern Image tex2;
    extern Image tex3;
    extern Image tex4;
    extern Image tex5;
    extern Image tex6;
    extern Image tex7;
    extern Image tex8;
    vec4 effect( vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords )
    {
        vec4 texcolor = Texel(tex, texture_coords);
        if (texIdx < 1.5) {
            return Texel(tex1, texture_coords);

        } else if (texIdx < 2.5) {
            return Texel(tex2, texture_coords);

        } else if (texIdx < 3.5) {
            return Texel(tex3, texture_coords);

        } else if (texIdx < 4.5) {
            return Texel(tex4, texture_coords);

        } else if (texIdx < 5.5) {
            return Texel(tex5, texture_coords);

        } else if (texIdx < 6.5) {
            return Texel(tex6, texture_coords);

        } else if (texIdx < 7.5) {
            return Texel(tex7, texture_coords);

        } else {
            return Texel(tex8, texture_coords);
        }
    }
    #endif
]])

local num = 100

local mesh = love.graphics.newMesh({
    {"VertexPosition", "float", 2},
    {"VertexTexCoord", "float", 2},
    {"tIdx", "float", 1}
}, num * 4, "triangles")

love.graphics.setShader(shader)
local textures = {
    "p1", "p2", "p6", "p7", "pjump", "ppoison"
}

local framesMap = {}
local srcs = {}
for i, key in ipairs(textures) do
    local tex = love.graphics.newImage("res/"..key..".png")
    shader:send("tex"..i, tex)
    srcs[i] = tex

    local tbl = json.decode(love.filesystem.read("res/"..key..".atlas"))
    framesMap[i] = {}
    for k, v in pairs(tbl.frames) do
        v.frame.name = k
        table.insert(framesMap[i], v.frame)
    end
end

local anims = {}
local verticesMap = {}
for i = 1, num do
    local idx = math.ceil(math.random() * #textures)
    local anim = {
        idx = idx,
        frames = framesMap[idx],
        src = srcs[idx],
        x = math.random() * 600,
        y = math.random() * 600
    }
    table.insert(anims, anim)
    
    local start = (i - 1) * 4
    table.insert(verticesMap, start + 1)
    table.insert(verticesMap, start + 2)
    table.insert(verticesMap, start + 3)

    table.insert(verticesMap, start + 1)
    table.insert(verticesMap, start + 3)
    table.insert(verticesMap, start + 4)
end

mesh:setVertexMap(verticesMap)

local time = 0
local interval = 0.15
function love.update(dt)
    time = time + dt
    for i, anim in ipairs(anims) do

        local index = math.floor(time / interval) % #anim.frames + 1
        local frame = anim.frames[index]

        local width, height = srcs[anim.idx]:getDimensions()
        local ux = frame.x / width
        local uy = frame.y / height
        local uw = frame.w / width
        local uh = frame.h / height
        local start = (i - 1) * 4
        mesh:setVertex(start + 1, anim.x, anim.y, ux, uy, anim.idx)
        mesh:setVertex(start + 2, anim.x + 100, anim.y, ux + uw, uy, anim.idx)
        mesh:setVertex(start + 3, anim.x + 100, anim.y + 100, ux + uw, uy + uh, anim.idx)
        mesh:setVertex(start + 4, anim.x, anim.y + 100, ux, uy + uh, anim.idx)
    end
end

function love.draw()
    love.graphics.setShader(shader)
    love.graphics.draw(mesh)
    love.graphics.setShader()
    stats.draw()
end